﻿#include "ComposePass.h"

#include "../ResourceManager/Dx2RootSignatureManager.h"
#include "../ResourceManager/Dx2ShaderAndLayoutManager.h"
#include "../../../Common/Singleton.h"


ComposePass::ComposePass()
{
}

void ComposePass::BuildRenderItems(std::vector<std::unique_ptr<RenderItem>>& allRitems, UINT& lastObjIndex)
{
}

void ComposePass::BuildPSOs(ID3D12Device* device, DXGI_FORMAT BackBufferFormat, DXGI_FORMAT DepthStencilFormat,
    bool _4xMsaaState, UINT _4xMsaaQuality)
{
    D3D12_GRAPHICS_PIPELINE_STATE_DESC compositePsoDesc;
    ZeroMemory(&compositePsoDesc,sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
	
    compositePsoDesc.InputLayout = {Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetInputLayout().data(),(UINT)Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetInputLayout().size()};
    compositePsoDesc.pRootSignature = Singleton<Dx2RootSignatureManager>::Instance()->GetRootSignature(RootSignatureType::Composite).Get();	

    compositePsoDesc.VS =
        {
        reinterpret_cast<BYTE*>(Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("compositeVS")->GetBufferPointer()),
        Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("compositeVS")->GetBufferSize()
    };
	   
    compositePsoDesc.PS =
        {
        reinterpret_cast<BYTE*>(Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("compositePS")->GetBufferPointer()),
        Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("compositePS")->GetBufferSize()
    };
    
    compositePsoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
    compositePsoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
    compositePsoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
    compositePsoDesc.SampleMask = UINT_MAX;
    compositePsoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
    compositePsoDesc.NumRenderTargets = 1;
    compositePsoDesc.RTVFormats[0] = BackBufferFormat;
    compositePsoDesc.SampleDesc.Count = _4xMsaaState? 4:1;
    compositePsoDesc.SampleDesc.Quality = _4xMsaaState? (_4xMsaaQuality - 1):0;
    compositePsoDesc.DSVFormat = DepthStencilFormat;
    
    compositePsoDesc.DepthStencilState.DepthEnable = false;
    compositePsoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
    compositePsoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;

    ThrowIfFailed(device->CreateGraphicsPipelineState(&compositePsoDesc,IID_PPV_ARGS(&mPso)));
}

void ComposePass::Draw(ID3D12GraphicsCommandList* cmdList, CD3DX12_GPU_DESCRIPTOR_HANDLE hGpuHandler, UINT srvHeapSize,
    UINT objCBByteSize, UINT matCBByteSize, UINT passCBByteSize, ID3D12Resource* objectCB, ID3D12Resource* matCB,
    ID3D12Resource* passCB, const PassConstants& passValue, ID3D12Resource* OutColorRenderTarget,
    D3D12_CPU_DESCRIPTOR_HANDLE OutColorRenderTargetView, D3D12_CPU_DESCRIPTOR_HANDLE OutDepthStentilView)
{
    cmdList->OMSetRenderTargets(1, &OutColorRenderTargetView, true, &OutDepthStentilView);

    cmdList->SetGraphicsRootSignature(Singleton<Dx2RootSignatureManager>::Instance()->GetRootSignature(RootSignatureType::Composite).Get());
    cmdList->SetPipelineState(mPso.Get());
    cmdList->SetGraphicsRootDescriptorTable(0, mBaseRTView);
    cmdList->SetGraphicsRootDescriptorTable(1, mEdgeRTview);
    DrawFullscreenQuad(cmdList);
}

void ComposePass::SetBaseAndEdgeMap(CD3DX12_GPU_DESCRIPTOR_HANDLE baseRTView, CD3DX12_GPU_DESCRIPTOR_HANDLE edgeRTView)
{
    mBaseRTView = baseRTView;
    mEdgeRTview = edgeRTView;
}

void ComposePass::DrawFullscreenQuad(ID3D12GraphicsCommandList* cmdList)
{
    cmdList->IASetVertexBuffers(0, 1, nullptr);
    cmdList->IASetIndexBuffer(nullptr);
    cmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    cmdList->DrawInstanced(6, 1, 0, 0);
}

